package sg.edu.nus.iss.billing.gui;

//Author: Tan Pic Cheng

import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;

import sg.edu.nus.iss.billing.controller.CustomerController;
import sg.edu.nus.iss.billing.entity.Address;
import sg.edu.nus.iss.billing.entity.Customer;
import sg.edu.nus.iss.billing.entity.RecordState;
import sg.edu.nus.iss.billing.exception.ControllerException;
import sg.edu.nus.iss.billing.exception.ValidationException;
import sg.edu.nus.iss.billing.gui.component.ErrorDialog;
import sg.edu.nus.iss.billing.gui.component.ValidateJTextField;
import sg.edu.nus.iss.billing.localization.MessageKeyManager;
import sg.edu.nus.iss.billing.validation.ValidationRule;

public class UpdateCustomerPanel extends DefaultFunctionPanel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static int HEIGHT = 30;

	private String fieldCustNRICUpper;
	private JLabel lblWarning = new JLabel();
	private JLabel lblCustHeader;
	private JLabel lblCustDetails;
	private CheckboxGroup cbg;
	private Checkbox ckNRIC;
	private Checkbox ckID;

	private Boolean ckState;

	private ValidateJTextField fieldCustNRIC;
	private JButton lookupButton;
	private JButton updateButton;
	private JButton resetButton;
	private JButton restoreButton;

	private JPanel tabPanel;
	private JPanel actionPanel;
	private JPanel restorePanel;
	private JTabbedPane tabbedPane;
	private JPanel custInfoPanel;
	private JPanel mobilePlanPanel;
	private JPanel digitalPlanPanel;
	private JPanel cablePlanPanel;
	private JPanel searchPanel;

	// 4 panels to display customer's personal information
	private UpdateCustomerFieldPanel custPanel;
	private UpdateCustomerAddressPanel custAdd;
	private UpdateCustomerContactPanel custContact;
	private UpdateCustomerMiscPanel custMisc;

	private CustomerController customerController;
	private Customer cust;

	public void storeData() {

	}

	public ValidateJTextField getFieldCustNRIC() {
		return fieldCustNRIC;
	}

	public void setFieldCustNRIC(ValidateJTextField fieldCustNRIC) {
		this.fieldCustNRIC = fieldCustNRIC;
	}

	public UpdateCustomerPanel() {
		customerController = new CustomerController();
		cust = SessionContext.getCustomer();
		if (cust != null && cust.getActive() == RecordState.ACTIVE) {
			super.init(null);
		} else {
			super.init("TOPONLY");
		}
	}

	public JPanel createTopPanel() {
		// Specify the top panel to display only NRIC & Customer Account Number
		// search options
		searchPanel = new JPanel(null);

		lblCustHeader = new JLabel(
				MessageKeyManager.getMessage("label.custHeader"));
		Font f = new Font("Arial", Font.BOLD, 12);
		lblCustHeader.setFont(f);
		lblCustHeader.setBounds(10, 15, 200, HEIGHT);
		searchPanel.add(lblCustHeader);

		JPanel displayOptions = displaySearchOptions();
		displayOptions.setBounds(0, 25, 800, 80);
		searchPanel.add(displayOptions);
		return searchPanel;

	}

	private JPanel displaySearchOptions() {
		// TODO Auto-generated method stub
		JPanel p = new JPanel(null);
		p.setPreferredSize(new Dimension(800, 80));

		lblCustDetails = new JLabel(
				MessageKeyManager.getMessage("label.custDetails"));
		lblCustDetails.setBounds(10, 15, 150, HEIGHT);
		p.add(lblCustDetails);

		cbg = new CheckboxGroup();
		ckNRIC = new Checkbox(MessageKeyManager.getMessage("label.nric"), true,
				cbg);
		ckID = new Checkbox(MessageKeyManager.getMessage("label.custAcct"),
				false, cbg);
		ckNRIC.setBounds(180, 15, 250, HEIGHT);
		ckID.setBounds(450, 15, 250, HEIGHT);

		p.add(ckNRIC);
		p.add(ckID);

		fieldCustNRIC = new ValidateJTextField(
				MessageKeyManager.getMessage("label.custDetails"));
		fieldCustNRIC.setBounds(180, 50, 250, 25);
		p.add(fieldCustNRIC);

		lookupButton = new JButton(
				MessageKeyManager.getMessage("button.lookup"));
		lookupButton.setBounds(450, 50, 100, 25);
		lookupButton.addActionListener(new lookupListener());
		p.add(lookupButton);

		return p;
	}

	public JPanel createBottomPanel() {
		tabPanel = new JPanel();

		// Create the tab pages
		// createMobilePlanPanel();
		// createDigitalPlanPanel();
		// creaetCablePlanPanel();
		// Create a tabbed pane
		tabbedPane = new JTabbedPane();
		tabbedPane.setPreferredSize(new Dimension(800, 600));
		custInfoPanel = createCustomerInfoPanel();
		tabbedPane.addTab(
				MessageKeyManager.getMessage("label.customerInfoPanel"),
				custInfoPanel);
		// tabbedPane.addTab( "Mobile Voice Plan ", mobilePlanPanel );
		// tabbedPane.addTab( "Digital Voice Plan", digitalPlanPanel );
		// tabbedPane.addTab( "Cable Plan", cablePlanPanel );
		tabPanel.add(tabbedPane);

		return tabPanel;
	}

	public JPanel createCustomerInfoPanel() {
		JPanel mainPanel = new JPanel();
		mainPanel.setLayout(new GridLayout(0, 2));

		custPanel = new UpdateCustomerFieldPanel(cust);
		custAdd = new UpdateCustomerAddressPanel(cust);
		custContact = new UpdateCustomerContactPanel(cust);
		custMisc = new UpdateCustomerMiscPanel(cust);

		mainPanel.add(custPanel);
		mainPanel.add(custAdd);
		mainPanel.add(custContact);
		mainPanel.add(custMisc);

		return mainPanel;
	}

	public Customer loadCustomerByNRIC(String nric) {

		Customer custObj = null;

		try {
			custObj = customerController.isNRICExist(nric);

		} catch (ControllerException ex) {
			ErrorDialog.showControllerErrorMessageDialog(ex);
		}

		return custObj;

	}

	public Customer loadCustomerByID(String id) {

		Customer custObj = null;

		try {

			custObj = customerController.getCustomerByAccount(id);

		} catch (ControllerException ex) {
			ex.printStackTrace();
		}

		return custObj;

	}

	public JPanel createActionButtonsPanel() {

		actionPanel = new JPanel();
		actionPanel.setLayout(new FlowLayout());

		updateButton = new JButton(
				MessageKeyManager.getMessage("button.update"));
		updateButton.addActionListener(new UpdateActionListener());

		resetButton = new JButton(MessageKeyManager.getMessage("button.reset"));
		resetButton.addActionListener(new ResetListener());

		actionPanel.add(updateButton);
		actionPanel.add(resetButton);

		return actionPanel;

	}

	private class ResetListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			custPanel.getFieldName().setText("");
			custPanel.getFieldEmail().setText("");
			custAdd.getFieldAdd1().setText("");
			custAdd.getFieldAdd2().setText("");
			custAdd.getFieldUnit().setText("");
			custAdd.getFieldPostal().setText("");
			custContact.getFieldHome().setText("");
			custContact.getFieldMobile().setText("");
			custContact.getFieldOffice().setText("");
			custMisc.getFieldInterests().setText("");
		}
	}

	public JPanel restoreCustomer() {
		restorePanel = new JPanel();

		restoreButton = new JButton(
				MessageKeyManager.getMessage("button.restore"));
		restorePanel.add("CENTER", restoreButton);

		ActionListener restore = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				cust.setActive(RecordState.ACTIVE);
				try {
					customerController.editCustomer(cust);
				} catch (ControllerException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				searchPanel.remove(lblWarning);
				searchPanel.updateUI();
				String msg = MessageKeyManager.getMessage(
						"msg.addCustomerRestore", fieldCustNRICUpper);
				lblWarning.setText(msg);
				searchPanel.add("CENTER", lblWarning);
				searchPanel.updateUI();
				restorePanel.setVisible(false);
				refreshBottomPanel(createBottomPanel());
				refreshActionButtonPanel(createActionButtonsPanel());
				searchPanel.remove(lblWarning);
				searchPanel.updateUI();
			}
		};

		restoreButton.addActionListener(restore);

		return restorePanel;
	}

	private Customer tryStorage(Customer customerObj)
			throws ValidationException {

		try {
			String salutation = custPanel.getSaluation().getSelectedItem();
			/* Account ID is using String */
			String custStatus = custPanel.getCustStatus();
			String custAcctID = custPanel.getStringCustAcctID();
			String name = custPanel.getFieldName().getValidatedText();
			String email = custPanel.getFieldEmail().getValidatedText();
			String add1 = custAdd.getFieldAdd1().getValidatedText();
			String add2 = custAdd.getFieldAdd2().getValidatedText();
			String unit = custAdd.getFieldUnit().getValidatedText();
			String postalCode = custAdd.getFieldPostal().getValidatedText();
			//int postalCode = Integer.parseInt(postal);
			String homeNo = custContact.getFieldHome().getValidatedText();
			String mobileNo = custContact.getFieldMobile().getValidatedText();
			String officeNo = custContact.getFieldOffice().getValidatedText();
			String interests = custMisc.getFieldInterests().getValidatedText();

			Address billing = new Address(add1, add2, unit, postalCode);
			if (custStatus == "ACTIVE")
				customerObj.setActive(RecordState.ACTIVE);
			customerObj.setAccountNumber(custAcctID);
			customerObj.setNRIC(customerObj.getNRIC());
			customerObj.setSalutation(salutation);
			customerObj.setName(name);
			customerObj.setEmail(email);
			customerObj.setContactNumber1(homeNo);
			customerObj.setContactNumber2(mobileNo);
			customerObj.setContactNumber3(officeNo);
			customerObj.setBillingAddress(billing);
			customerObj.setInterests(interests);
			/*
			 * ID is the system value and will handle by Dayong only, so do not
			 * need to set in GUI
			 */
			// customerObj.setId(custID);
		} catch (ValidationException ex) {
			throw ex;
		}
		return customerObj;
	}

	private class UpdateActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			try {
				Customer custObj = tryStorage(cust);
				customerController.editCustomer(custObj);
				JOptionPane
						.showMessageDialog(
								null,
								MessageKeyManager
										.getMessage("msg.updateCustomerNotification"),
								MessageKeyManager
										.getMessage("msg.updateCustomerNotificationTitle"),
								JOptionPane.INFORMATION_MESSAGE);
				tabPanel.removeAll();
				actionPanel.removeAll();
				tabPanel.updateUI();
				actionPanel.updateUI();
				new ResetListener().actionPerformed(null);
			} catch (ValidationException ex) {
				ErrorDialog.showValidationErrorMessageDialog(ex);
			} catch (ControllerException ex) {
				ErrorDialog.showControllerErrorMessageDialog(ex);
			} catch (Exception ex) {
				ErrorDialog.showUnhandledErrorMessageDialog(ex);
			}
		}
	}

	public class lookupListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub

			Checkbox selectedCheckbox;
			selectedCheckbox = cbg.getSelectedCheckbox();

			if (selectedCheckbox == ckNRIC)
				ckState = true;
			else
				ckState = false;

			try {
				if (tabPanel != null) {
					tabPanel.removeAll();
					tabPanel.updateUI();
				}
				if (actionPanel != null) {
					actionPanel.removeAll();
					actionPanel.updateUI();
				}
				if (lblWarning.isShowing() == true) {
					searchPanel.remove(lblWarning);
					searchPanel.updateUI();
				}
				fieldCustNRICUpper = fieldCustNRIC.getText().toUpperCase().trim();
				fieldCustNRIC.setText(fieldCustNRICUpper);
				if (ckState == true) {
					fieldCustNRIC.setRules(ValidationRule.NOT_NULL,	ValidationRule.NRIC);
					cust = loadCustomerByNRIC(fieldCustNRIC.getValidatedText());
					if (cust == null) {
						String msg = "Customer with NRIC: " + fieldCustNRIC.getText()+ " is a new customer!";
						lblWarning.setText(msg);
						lblWarning.setBounds(180, 100, 400, 20);
						lblWarning.setVerticalTextPosition(SwingConstants.BOTTOM);
						searchPanel.add(lblWarning);
						searchPanel.updateUI();
					} else if (cust != null
							&& cust.getActive() == RecordState.DELETED) {
						SessionContext.setCustomer(cust);
						if (restorePanel != null)
							restorePanel.setVisible(true);
						String msg = MessageKeyManager.getMessage(
								"msg.addCustomerDeleteByNRIC",
								fieldCustNRIC.getText());
						lblWarning.setText(msg);
						lblWarning.setBounds(180, 100, 400, 20);
						lblWarning.setVerticalTextPosition(SwingConstants.BOTTOM);
						searchPanel.add(lblWarning);
						searchPanel.updateUI();
						refreshBottomPanel(restoreCustomer());
					} else {
						SessionContext.setCustomer(cust);
						refreshBottomPanel(createBottomPanel());
						refreshActionButtonPanel(createActionButtonsPanel());
					}
				} else {
					fieldCustNRIC.setRules(ValidationRule.NOT_NULL,ValidationRule.ACCOUNT_NUMBER);
					cust = loadCustomerByID(fieldCustNRIC.getValidatedText());

					if (cust == null) {
						String msg = "Customer with Customer Account Number: " + fieldCustNRIC.getText() + " is a new customer!";

						lblWarning = new JLabel(msg);
						lblWarning.setBounds(180, 100, 500, 20);
						lblWarning.setVerticalTextPosition(SwingConstants.BOTTOM);

						searchPanel.add(lblWarning);
						searchPanel.updateUI();

					} else if (cust != null
							&& cust.getActive() == RecordState.DELETED) {
						SessionContext.setCustomer(cust);
						String msg = MessageKeyManager.getMessage("msg.addCustomerDeleteByAccount", fieldCustNRIC.getText());
						lblWarning.setText(msg);
						lblWarning.setBounds(140, 100, 550, 20);
						lblWarning.setVerticalTextPosition(SwingConstants.BOTTOM);
						searchPanel.add(lblWarning);
						searchPanel.updateUI();
						refreshBottomPanel(restoreCustomer());
					} else {
						SessionContext.setCustomer(cust);
						refreshBottomPanel(createBottomPanel());
						refreshActionButtonPanel(createActionButtonsPanel());
					}
				}
				fieldCustNRIC.setText("");
			} catch (ValidationException ex) {
				ErrorDialog.showValidationErrorMessageDialog(ex);
			}
		}
	}

}
